#include <sys_config.h>

//#ifdef SHOW_PICS
//#if(SHOW_PICS == SHOW_SINGLE_PIC)
#ifdef PIP_PNG_GIF

#include <basic_types.h>
#include <mediatypes.h>
#include <api/libc/printf.h>
#include <api/libc/string.h>
#include <hld/hld_dev.h>
#include <hld/ge/ge.h>
#include <hld/dis/vpo.h>
#include "test0_png.h"
#include <hld/osd/osddrv.h>
#include <hld/decv/vdec_driver.h>
#include <hld/decv/decv.h>

#include <api/libimagedec/imagedec.h>
#include <api/libmp/png.h>
#include <api/libmp/pe.h>
//#include "../../image_engine.h"
//#include "../../plugin.h"
//#include <api/libfs2/stdio.h>
#include <api/libfs2/stdio.h>
#include "ad_pic_png.h"


//#define AD_PNG_DEBUG
#ifdef AD_PNG_DEBUG
#define AD_PNG_PRINTF	libc_printf
#else
#define AD_PNG_PRINTF(...)	do{}while(0)
#endif

//#define PNG_OUT_CLUT8_PIC


static struct png_instance *png = NULL;

static UINT8 *png_file_addr;
static UINT32 png_file_size;
static INT32 png_input_pos = 0;

static ad show_file[1] =
{

	{
		0,
		(UINT8 *)test0_png,
		sizeof(test0_png),
		{0,0,800,600}
	},

};
static int png_read_data(UINT32 fh,BYTE *buf, UINT32 size)
{
	UINT32 read_pos;
	UINT32 read_len;

	read_pos = png_input_pos+size;
	if(read_pos>png_file_size)
	{
		read_len = png_file_size-png_input_pos;
		MEMCPY((void *)buf, (void *)(png_file_addr+png_input_pos), read_len);
		png_input_pos += read_len;
		return read_len;
	}
	else
	{
		MEMCPY((void *)buf, (void *)(png_file_addr+png_input_pos), size);
		png_input_pos+=size;
		return size;
	}
}

static int png_seek_data(UINT32 fh,long offset, UINT32 origin)
{
	if(origin == 0)
	{
		png_input_pos = (UINT32)offset;
		return TRUE;
	}
	return FALSE;
}

static int png_tell_pos(UINT32 fh)
{
	return png_input_pos;
}

static PNG_RET png_view_routine_ge(struct png_image *img, struct png_view_par *par)
{
    ge_rect_t dst_rect, src_rect;
	//ge_surface_desc_t *src_surf, *dst_surf;
	struct ge_device *ge_dev;
	INT32 ret;
    ge_operating_entity entity;
    UINT32 layer_id = 0;
    UINT32 region_id =0;
    UINT32 cmd_hdl = 0;

	ge_dev = (struct ge_device *)dev_get_by_id(HLD_DEV_TYPE_GE, 0);
    ge_cmd_list_hdl cmd_list = ge_cmd_list_create(ge_dev, 10);
	if (ge_dev == NULL)
	{
		AD_PNG_PRINTF("%s() ge device find failed!\n", __FUNCTION__);
		return -1;
	}

	//src_surf = (ge_surface_desc_t *)ad_pic_get_ge_surface(AD_SRC_SURFACE);
	//dst_surf = (ge_surface_desc_t *)ad_pic_get_ge_surface(AD_DST_SURFACE);

	//if (src_surf == NULL || dst_surf == NULL)
	//	return -1;

	src_rect.left = 0;
	src_rect.top = 0;
    if(ALI_S3821 == sys_ic_get_chip_id())
    {
        src_rect.width = img->scale_w;//img->hw_stride;//img->hw_stride;
	    src_rect.height = img->scale_h;//img->hw_y_stride;//img->hw_y_stride;
	    entity.pixel_pitch = img->hw_stride;//src_rect.width;
    }
    else
    {
        src_rect.width = img->size.w;//img->hw_stride;//img->hw_stride;
	    src_rect.height = img->size.h;//img->hw_y_stride;//img->hw_y_stride;
	    entity.pixel_pitch = src_rect.width;//src_rect.width;
    }


	dst_rect.left = par->pos.x;
	dst_rect.top = par->pos.y;
	dst_rect.width = src_rect.width;
	dst_rect.height = src_rect.height;

    osal_cache_flush(img->graphic_buf, src_rect.width * src_rect.height * 4 );
    ge_cmd_list_new(ge_dev,cmd_list,GE_COMPILE_AND_EXECUTE);
    ge_gma_set_region_to_cmd_list(ge_dev,layer_id,region_id,cmd_list);

    entity.color_format = GE_PF_ARGB8888;
	entity.base_address = (UINT8 *)img->graphic_buf;
	entity.data_decoder = GE_DECODER_DISABLE;
    entity.modify_flags = GE_BA_FLAG_ADDR|GE_BA_FLAG_FORMAT|GE_BA_FLAG_PITCH;

    cmd_hdl = ge_cmd_begin(ge_dev,cmd_list,GE_DRAW_BITMAP);
	ge_set_operating_entity(ge_dev,cmd_hdl,GE_PTN,&entity);
	ge_set_clut_rgb_order(ge_dev,cmd_hdl,GE_RGB_ORDER_ARGB);
    //ge_set_rgb_expansion(ge_dev,cmd_hdl,GE_SRC, GE_RGB_EXPAN_MSB_TO_LSB);
	ge_set_xy(ge_dev,cmd_hdl,GE_DST,dst_rect.left,dst_rect.top);
	ge_set_xy(ge_dev,cmd_hdl,GE_SRC,dst_rect.left,dst_rect.top);
	ge_set_xy(ge_dev,cmd_hdl,GE_PTN,src_rect.left,src_rect.top);
	ge_set_wh(ge_dev,cmd_hdl,GE_DST_PTN,dst_rect.width,dst_rect.height);
    //osal_task_sleep(100);
	ge_cmd_end(ge_dev,cmd_hdl);
    //osal_task_sleep(100);

	return ret;
//#endif


}

#define PNG_FILE_SIZE		762

//#define PNG_BIT_BUF			(__MM_IMAGEDEC_BUF_ADDR&0x8FFFFFFF)  //0xA1100000
#define PNG_BIT_SIZE		(64*1024)//0x8000

//#define PNG_DEC_BUF		    ((PNG_BIT_BUF + PNG_BIT_SIZE)&0x8FFFFFFF)  //0xA1200000
//#define PNG_DEC_SIZE		0x84600  //w*h*4 + 0x30000 //0x200000
#define PNG_DEC_SIZE		0x90000//0x8e900

//void ad_png_init(void)
void ad_pic_png_init(void)
{
	struct png_cfg cfg;
    UINT32 len = __MM_MP_BUFFER_ADDR+__MM_MP_BUFFER_LEN -__MM_TTX_BS_START_ADDR-__MM_TTX_BS_LEN;
	/*MEMSET((void *)&cfg,0,sizeof(struct png_cfg));
	cfg.bit_buf_start = (UINT8 *)__MM_MP_BUFFER_ADDR;
	cfg.bit_buf_size = PNG_BIT_SIZE;
	cfg.dec_buf = (UINT8 *)(__MM_MP_BUFFER_ADDR + PNG_BIT_SIZE);
	cfg.dec_buf_totalsize =PNG_DEC_SIZE;
	png = png_open(&cfg);*/
	MEMSET((void *)&cfg,0,sizeof(struct png_cfg));
	cfg.bit_buf_size = PNG_BIT_SIZE;
#ifdef DUAL_ENABLE
	cfg.bit_buf_start = (UINT8 *)__MM_MP_BUFFER_ADDR;
	cfg.dec_buf_start = (UINT8 *)(__MM_MP_BUFFER_ADDR + PNG_BIT_SIZE);
    cfg.dec_buf_size = __MM_MP_BUFFER_LEN - PNG_BIT_SIZE;
#else
    cfg.bit_buf_start = (UINT8 *)__MM_TTX_BS_START_ADDR+__MM_TTX_BS_LEN;
	cfg.dec_buf_start = cfg.bit_buf_start + PNG_BIT_SIZE;
    cfg.dec_buf_size = len - PNG_BIT_SIZE;
#endif

    cfg.dec_buf = cfg.dec_buf_start;
    cfg.dec_buf_totalsize = cfg.dec_buf_size;
    if(ALI_S3821== sys_ic_get_chip_id())
        image_png_init();
    png = png_open(&cfg);
}

//static void ad_png_dec(struct OSDRect *rect)
static void ad_pic_png_dec(struct OSDRect *rect)
{
	struct png_file file;
	MEMSET((void *)&file, 0, sizeof(struct png_file));
	file.handle = 0x56;
	file.fread = png_read_data;
	file.fseek = png_seek_data;
	file.ftell = png_tell_pos;

	struct png_image img;
	MEMSET((void *)&img, 0, sizeof(struct png_image));
#ifdef PNG_OUT_CLUT8_PIC
	img.cf_defined = PNG_CF_DEFINED_AUTOMATICALLY;
#else
	img.cf_defined = PNG_CF_DEFINED_MANUALLY;
#endif
	img.plt_type = PNG_PLT_AYCBCR8888;

	png_dec(png, &file, &img, PNG_SYNC);  //the synchronous mode
	struct png_view_par view_par;
	MEMSET((void *)&view_par, 0, sizeof(struct png_view_par));
	view_par.handle0 = 0;
	view_par.pos.x = 70;//rect->uLeft;
	view_par.pos.y = 10;//0;  //rect->uTop;
    if(ALI_S3821 != sys_ic_get_chip_id())
    {
    	png_view(png, &img, &view_par, png_view_routine_ge);
    }
    else
        png_view_routine_ge(&img, &view_par);

}

//INT32 ad_png_draw(UINT8* file, UINT32 file_len, struct OSDRect *rect)
INT32 ad_pic_png_draw(UINT8* file, UINT32 file_len, struct OSDRect *rect)
{
	png_input_pos = 0;
	png_file_addr = (UINT8*)file;
	png_file_size = file_len;

	ad_pic_png_init();
	ad_pic_png_dec(rect);
	return SUCCESS;
}

void ad_pic_png_close(void)
{

	if (png == NULL)
		return;
/*	png_stop(png);
*/	png_close(png);
    png = NULL;

//	png->busy = 0;  //for the synchronous mode for png_dec(png, &file, &img, PNG_SYNC);
}

void show_png_pic(UINT8 num)
#if 1
{
#if 0
	ad *ad = NULL;
	struct sto_device *sto_flash_dev;
	UINT8 *logo_buf;
	UINT32 addr,len;

	api_get_chunk_add_len(0x0AF50100,&addr,&len);
	logo_buf = (UINT8 *)MALLOC(len);
	sto_flash_dev = (struct sto_device *)dev_get_by_id(HLD_DEV_TYPE_STO, 0);
	sto_get_data(sto_flash_dev, (UINT8 *)logo_buf, addr, len);

	num %= (sizeof(show_file)/sizeof(ad));
	ad=&show_file[num];
#else
    ad *ad = NULL;
    UINT8 *logo_buf;
	UINT32 addr,len;
    FILE *fp_handle;

    num %= (sizeof(show_file)/sizeof(ad));
	ad=&show_file[num];
	fp_handle= fopen("/mnt/uda1/ad_png.png", "rb");
    if(fp_handle == NULL)
    {
        AD_PNG_PRINTF(" fb_handle is null\n");
        return;
    }

	AD_PNG_PRINTF("fp_handle=%x\n",fp_handle);
    UINT32 readsize=0;
	len=264*1024;
	logo_buf = (UINT8 *)MALLOC(len);

	readsize=fread(logo_buf,1,len,fp_handle);/*actual read file bytes*/
	AD_PNG_PRINTF("readsize=%d\n",readsize);
	AD_PNG_PRINTF("logo_buf=%x\n",logo_buf);
    ad->rect.uLeft=0;
	ad->rect.uTop=0;
	ad->rect.uHeight=240;
	ad->rect.uWidth=360;
#endif
	ad_pic_png_draw(logo_buf, len, &(ad->rect));

    FREE(logo_buf);
}
#else
{
    ad *ad = NULL;

    num %= (sizeof(show_file)/sizeof(ad));
    ad=&show_file[num];
    //ad_pic_show(ad->file, (UINT8 *)ad->buf, ad->len, ad->rect);
    ad_pic_png_draw((UINT8 *)ad->buf, ad->len,&(ad->rect));
}
#endif
//#endif
//#endif
#endif
